﻿#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using System;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = UnityEngine.Debug;

[System.Reflection.Obfuscation(Exclude = true)]
public class ILRuntimeCLRBinding
{
    static Stopwatch watch = new Stopwatch();

    [MenuItem("ILRuntime/注入热更代码到 Assembly-CSharp.dll", false, 12)]
    static void InjectorDll()
    {
        if (EditorApplication.isCompiling || Application.isPlaying)
        {
            //EditorUtility.DisplayDialog("警告", "你当前处于编译或者运行中，请等待编译完成或者停止运行", "了解");
            return;
        }

        watch.Reset();
        watch.Start();
        LCL.Injector.RunGen("InjectIL");
        UnityEngine.Debug.Log("InjectIL time:" + watch.ElapsedMilliseconds + " ms");
        AssetDatabase.Refresh();
    }

    [MenuItem("ILRuntime/一键生成热更代码", false, 11)]
    static void GenerateInjectionInfo()
    {
        if (EditorApplication.isCompiling || Application.isPlaying)
        {
            EditorUtility.DisplayDialog("警告", "你当前处于编译或者运行中，请等待编译完成或者停止运行", "了解");
            return;
        }
        //if (!EditorUtility.DisplayDialog("警告", "你是否需要重新生成热更新字段信息？", "需要", "按错了"))
        //{
        //    return;
        //}

        //watch.Reset();
        //watch.Start();
        GenerateCLRBinding();
        LCL.Injector.RunGen("OneKey");
        //UnityEngine.Debug.Log("GenStaticField time:" + watch.ElapsedMilliseconds + " ms");
        //AssetDatabase.Refresh();
    }

    [MenuItem("ILRuntime/还原 Assembly-CSharp.dll", false, 13)]
    static void RestoreDll()
    {
        if (EditorApplication.isCompiling || Application.isPlaying)
        {
            EditorUtility.DisplayDialog("警告", "你当前处于编译或者运行中，请等待编译完成或者停止运行", "了解");
            return;
        }
        
        // 随便找了一个文件来重新导入一下，这样就可以让Unity重新编译dll了
        AssetDatabase.ImportAsset("Assets/ILRuntime/ILRuntime/Other/NeedAdaptorAttribute.cs");
        AssetDatabase.Refresh();
    }



    [MenuItem("ILRuntime/生成基础类的CLR绑定代码")]
    static void GenerateCLRBinding()
    {
        List<Type> types = new List<Type>();
        types.Add(typeof(int));
        types.Add(typeof(float));
        types.Add(typeof(long));
        types.Add(typeof(object));
        types.Add(typeof(string));
        types.Add(typeof(Array));
        types.Add(typeof(Vector2));
        types.Add(typeof(Vector3));
        types.Add(typeof(Quaternion));
        types.Add(typeof(GameObject));
        types.Add(typeof(UnityEngine.Object));
        types.Add(typeof(Transform));
        types.Add(typeof(RectTransform));
        //types.Add(typeof(MonoBehaviour));
        //types.Add(typeof(CLRBindingTestClass));
        types.Add(typeof(Time));
        types.Add(typeof(Debug));
        //所有DLL内的类型的真实C#类型都是ILTypeInstance
        types.Add(typeof(List<ILRuntime.Runtime.Intepreter.ILTypeInstance>));

        ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(types, "Assets/ILRuntime/Generated/CLRBinding");
        AssetDatabase.Refresh();

    }

    [MenuItem("ILRuntime/生成hotfix.dll中使用到的CLR绑定代码")]
    static void GenerateCLRBindingByAnalysis()
    {
        //用新的分析热更dll调用引用来生成绑定代码
        ILRuntime.Runtime.Enviorment.AppDomain domain = new ILRuntime.Runtime.Enviorment.AppDomain();
        using (System.IO.FileStream fs = new System.IO.FileStream("Assets/StreamingAssets/EA4A55FD.dll.bytes", System.IO.FileMode.Open, System.IO.FileAccess.Read))
        {
            domain.LoadAssembly(fs);
        }
        //Crossbind Adapter is needed to generate the correct binding code
        InitILRuntime(domain);
        ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(domain, "Assets/ILRuntime/Generated/CLRBinding");
    }

    static void InitILRuntime(ILRuntime.Runtime.Enviorment.AppDomain domain)
    {
        //这里需要注册所有热更DLL中用到的跨域继承Adapter，否则无法正确抓取引用
        //domain.RegisterCrossBindingAdaptor(new MonoBehaviourAdapter());
        //domain.RegisterCrossBindingAdaptor(new CoroutineAdapter());
        //domain.RegisterCrossBindingAdaptor(new InheritanceAdapter());
    }
}
#endif
